﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Net.Http;
using System.Net;
using Newtonsoft.Json.Linq;
using LunchCommand.Models.Logging;

namespace LunchCommand.Services.Maps
{
    /// <summary>
    /// Implementation of the map service for Bing Maps
    /// </summary>
    public class BingMapsService : IMapService
    {
        private const string BingUrl = "http://dev.virtualearth.net";

        private const string RoutesResource = "/REST/v1/Routes";

        /// <summary>
        /// The logger to log with
        /// </summary>
        private ILogger Logger { get; set; }

        public BingMapsService(String key, ILogger logger)
        {
            this.Key = key;
            this.Logger = logger;
        }

        /// <summary>
        /// Unique key to identify this application to Bing maps
        /// </summary>
        public String Key { get; set; }

        public TimeSpan? GetTravelTime(string startAddress, string endAddress)
        {
            try
            {
                if (String.IsNullOrWhiteSpace(startAddress) || String.IsNullOrWhiteSpace(endAddress))
                {
                    return null;
                }

                this.Logger.Log(LogEntryType.Info, String.Format("Looking up travel time from [{0}] to [{1}]", startAddress, endAddress));

                var client = new WebClient();

                var query = HttpUtility.ParseQueryString(string.Empty);

                // waypoint 1
                query.Add("wp.1", startAddress);

                // waypont 2
                query.Add("wp.2", endAddress);

                // distance units, not that it matters
                query.Add("du", "mi");

                // we don't need any other crap, just the summary
                query.Add("ra", "routeSummariesOnly");

                // the key
                query.Add("key", this.Key);

                var queryString = query.ToString();

                var uri = String.Format("{0}{1}?{2}", BingUrl, RoutesResource, queryString);

                this.Logger.Log(LogEntryType.Info, String.Format("Requesting map info from: {0}", uri));

                var json = client.DownloadString(uri);

                this.Logger.Log(LogEntryType.Info, String.Format("Got response: {0}", json));

                var jsonParsed = JObject.Parse(json);

                var travelSeconds = Int32.Parse((String)jsonParsed["resourceSets"][0]["resources"][0]["travelDurationTraffic"]);

                this.Logger.Log(LogEntryType.Info, String.Format("Travel time in seconds: {0}", travelSeconds));

                return new TimeSpan(0, 0, travelSeconds);
            }
            catch (ArgumentException e) { }
            catch (Exception e)
            {
                this.Logger.Log(LogEntryType.Error, "Error getting map data");
                this.Logger.Log(LogEntryType.Error, e.Message);
                this.Logger.Log(LogEntryType.Error, e.StackTrace);
            }

            return null;
        }
    }
}